﻿//==============================================================================
// File: RcpWindowManager.cs
// Created: 2010-05-28
// Author: Piotr Włodek, Arek Świerczek
//==============================================================================
// This file is a part of MAMMOTH project.
// Copyright (C) 2010 AGH University of Science and Technology, Krakow.
// https://caribou.iisg.agh.edu.pl/trac/mammoth
//
// Mammoth is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// Mammoth is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public License
// along with Mammoth. If not, see http://www.gnu.org/licenses/.
//==============================================================================

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace WpfRcp.Controls
{
    [TemplatePart(Name = PART_Detach, Type = typeof(Button))]
    [TemplatePart(Name = PART_Close, Type = typeof(Button))]
    public class TabMenuItem : TabItem, ITabMenuItem
    {
        public static readonly ResourceKey DetachedTabMenuItemWindowStyleKey =
            new ComponentResourceKey(typeof(TabMenuItem), "DetachedTabMenuItemWindowStyleKey");

        private const string PART_Detach = "PART_Detach";
        private const string PART_Close = "PART_Close";

        public static readonly DependencyProperty DetachedMarginProperty =
            DependencyProperty.Register("DetachedMargin", typeof(Thickness), typeof(TabMenuItem), new UIPropertyMetadata(new Thickness()));

        public static readonly DependencyProperty CornerRadiusProperty =
            DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(TabMenuItem),
                                        new PropertyMetadata(new CornerRadius(0.0)));
        
        public static readonly DependencyProperty IsDetachableProperty =
            DependencyProperty.Register("IsDetachable", typeof(bool), typeof(TabMenuItem),
                                        new PropertyMetadata(false));

        public static readonly DependencyProperty IsCloseableProperty =
            DependencyProperty.Register("IsCloseable", typeof(bool), typeof(TabMenuItem), new PropertyMetadata(false));

        public static readonly RoutedEvent DetachEvent = EventManager.RegisterRoutedEvent("Detach", RoutingStrategy.Bubble,
                                                                                          typeof(RoutedEventHandler), typeof(TabMenuItem));

        public static readonly RoutedEvent CloseEvent = EventManager.RegisterRoutedEvent("Close", RoutingStrategy.Bubble,
                                                                                         typeof(RoutedEventHandler), typeof(TabMenuItem));

        static TabMenuItem()
        {
            // This OverrideMetadata call tells the system that this element wants
            // to provide a style that is different than its base class
            DefaultStyleKeyProperty.OverrideMetadata(typeof(TabMenuItem),
                                                     new FrameworkPropertyMetadata(typeof(TabMenuItem)));
        }

        protected override void OnMouseDown(MouseButtonEventArgs e)
        {
            if (e.MiddleButton == MouseButtonState.Pressed)
            {
                CloseTabMenuItem();
            }

            base.OnMouseDown(e);
        }

        protected override void OnPreviewMouseRightButtonDown(MouseButtonEventArgs e)
        {
            var item = e.Source as TabMenuItem;
            if (item != null)
            {
                item.IsSelected = true;
                item.Focus();
            }

            base.OnPreviewMouseRightButtonDown(e);
        }

        public CornerRadius CornerRadius
        {
            get { return (CornerRadius)GetValue(CornerRadiusProperty); }
            set { SetValue(CornerRadiusProperty, value); }
        }

        public bool IsDetachable
        {
            get { return (bool)GetValue(IsDetachableProperty); }
            set { SetValue(IsDetachableProperty, value); }
        }

        public bool IsCloseable
        {
            get { return (bool)GetValue(IsCloseableProperty); }
            set { SetValue(IsCloseableProperty, value); }
        }

        public Thickness DetachedMargin
        {
            get { return (Thickness)GetValue(DetachedMarginProperty); }
            set { SetValue(DetachedMarginProperty, value); }
        }

        public event RoutedEventHandler Detach
        {
            add { AddHandler(DetachEvent, value); }
            remove { RemoveHandler(DetachEvent, value); }
        }

        protected virtual void RaiseDetachEvent(DetachRoutedEventArgs args)
        {
            RaiseEvent(args);
        }

        public event RoutedEventHandler Close
        {
            add { AddHandler(CloseEvent, value); }
            remove { RemoveHandler(CloseEvent, value); }
        }

        protected virtual void RaiseCloseEvent(RoutedEventArgs args)
        {
            RaiseEvent(args);
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            var button = GetTemplateChild(PART_Detach) as Button;
            if (button != null)
            {
                button.Click += OnDetachClicked;
            }

            button = GetTemplateChild(PART_Close) as Button;
            if (button != null)
                button.Click += OnCloseClicked;
        }

        private void OnCloseClicked(object sender, RoutedEventArgs e)
        {
            CloseTabMenuItem();
            e.Handled = true;
        }

        private void OnDetachClicked(object sender, RoutedEventArgs e)
        {
            DetachTabMenuItem();
            e.Handled = true;
        }

        public void CloseTabMenuItem()
        {
            if (IsCloseable)
            {
                RaiseCloseEvent(new RoutedEventArgs(CloseEvent, this));
            }
        }

        public void DetachTabMenuItem()
        {
            if (IsDetachable)
            {
                DependencyObject parent = VisualTreeHelper.GetParent(this);
                parent = VisualTreeHelper.GetParent(parent);
                parent = VisualTreeHelper.GetParent(parent);

                RaiseDetachEvent(new DetachRoutedEventArgs(DetachEvent, parent as TabMenu, this));
            }
        }

        public DependencyProperty HeaderTitleProperty
        {
            get { return HeaderedContentControl.HeaderProperty; }
        }

    }

    public class DetachRoutedEventArgs : RoutedEventArgs
    {
        public TabMenu ParentTabMenu { get; private set; }

        public DetachRoutedEventArgs(RoutedEvent routedEvent, TabMenu tabMenu, object sender)
            : base(routedEvent, sender)
        {
            ParentTabMenu = tabMenu;   
        }
    }
}